Vue 3 Composition API vs Options API 
一、Options API 的局限性 
在 Vue 2 中,Options API(通过 data 、 methods 、 computed 等选项组织代码)存在以下问题:
- 逻辑分散 
 同一功能的代码被拆分到不同选项中(如- data定义变量,- methods定义方法,- watch监听变化),导致代码阅读和维护困难。javascript- // Options API 示例:一个计数器逻辑被分散到多个选项中 export default { data() { return { count: 0 } }, methods: { increment() { this.count++ } }, watch: { count(newVal) { console.log('Count changed:', newVal) } } }1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
- 逻辑复用困难 
 通过- mixins或高阶组件复用逻辑时,存在 命名冲突、来源不透明 等问题。
- 类型支持薄弱 
 Vue 2 的- this上下文导致 TypeScript 类型推断困难,难以实现严格的类型检查。
- 大型组件臃肿 
 复杂组件的代码量增加后,功能逻辑难以拆分和复用。
二、Composition API 的核心优势 
1. 逻辑聚合与自由组织 
Composition API 允许将 同一功能的代码集中在一起(按逻辑功能组织),而不是分散在不同选项中。
vue
<script setup>
import { ref, watch } from 'vue'
// 计数器逻辑集中在一个区域
const count = ref(0)
const increment = () => { count.value++ }
watch(count, (newVal) => {
  console.log('Count changed:', newVal)
})
</script>1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
2. 更灵活的逻辑复用 
通过 组合式函数( useXxx ) 封装逻辑,实现类似 React Hooks 的复用方式,避免 Mixin 的缺陷。
javascript
// 复用逻辑:封装计数器功能
export function useCounter(initialValue = 0) {
  const count = ref(initialValue)
  const increment = () => { count.value++ }
  return { count, increment }
}
// 在组件中使用
const { count, increment } = useCounter(10)1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
3. 更好的 TypeScript 支持 
- 变量和函数类型可显式声明,无需依赖 this上下文。
- 组合式函数天然支持类型推导。
typescript
import { ref } from 'vue'
// 明确的类型声明
const count = ref<number>(0)
const increment = (): void => { count.value++ }1
2
3
4
5
2
3
4
5
4. 更细粒度的响应式控制 
- 使用 ref和reactive显式声明响应式数据。
- 通过 computed和watch精确管理依赖关系。
javascript
const state = reactive({ user: null, loading: false })
const fullName = computed(() => state.user ? `${state.user.first} ${state.user.last}` : '')1
2
2
5. 更灵活的代码结构 
- 支持在函数作用域内声明生命周期钩子。
- 逻辑块可自由拆分和组合。
javascript
// 异步获取数据的逻辑
const fetchData = async () => {
  const data = await api.get('/data')
  state.data = data
}
onMounted(fetchData) // 在 mounted 时执行1
2
3
4
5
6
2
3
4
5
6
三、Composition API vs Options API 对比 
| 特性 | Options API | Composition API | 
|---|---|---|
| 代码组织 | 按选项类型(data/methods 等)分割 | 按逻辑功能聚合 | 
| 逻辑复用 | Mixins(易冲突) | 组合式函数(无命名冲突) | 
| 响应式控制 | 隐式声明(data 返回对象) | 显式声明(ref/reactive) | 
| TypeScript 支持 | 弱(依赖 this上下文) | 强(函数作用域 + 类型推断) | 
| 生命周期管理 | 分散在选项(created/mounted 等) | 集中通过函数调用(onMounted 等) | 
| 代码可读性(复杂组件) | 低(逻辑分散) | 高(功能模块化) | 
| 灵活性 | 低(固定结构) | 高(自由组合) | 
四、Composition API 解决的问题场景 
1. 跨组件逻辑复用 
- Options API:通过 Mixins 复用,但可能引发命名冲突,且来源不透明。
- Composition API:通过函数组合,明确依赖关系,避免冲突。
2. 复杂组件维护 
- Options API:随着功能增加,代码分散到多个选项,难以追踪。
- Composition API:将同一功能的变量、方法、监听集中管理。
javascript
// 示例:用户认证逻辑集中管理
const { user, login, logout } = useAuth()
const { orders, loadOrders } = useUserOrders(user)1
2
3
2
3
3. TypeScript 项目开发 
- Options API:类型推导困难,需要额外类型声明。
- Composition API:天然支持类型推断,减少类型错误。
4. 动态逻辑组合 
- Options API:逻辑在选项中固定,难以动态调整。
- Composition API:可根据条件动态组合不同逻辑。
javascript
if (needsTracking) {
  useAnalytics() // 按需加入统计逻辑
}1
2
3
2
3
五、实际应用示例:封装数据请求逻辑 
使用 Composition API 封装: 
javascript
// utils/useFetch.js
import { ref, onMounted } from 'vue'
export function useFetch(url) {
  const data = ref(null)
  const loading = ref(false)
  const error = ref(null)
  const fetchData = async () => {
    try {
      loading.value = true
      const response = await fetch(url)
      data.value = await response.json()
    } catch (err) {
      error.value = err
    } finally {
      loading.value = false
    }
  }
  onMounted(fetchData) // 自动在组件挂载时执行
  return { data, loading, error, retry: fetchData }
}
// 在组件中使用
const { data, loading } = useFetch('/api/user')1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
六、总结 
Composition API 的核心价值在于:
- 逻辑自由聚合:告别代码碎片化,按功能组织代码。
- 复用性革命:通过函数组合替代 Mixins,实现无副作用的逻辑复用。
- 类型友好:与 TypeScript 深度协同,提升代码健壮性。
- 响应式控制:显式管理依赖关系,优化性能。
尽管 Options API 仍适用于简单场景,但在 中大型项目 或 需要高复用性 的场景下,Composition API 提供了更现代的解决方案,代表了 Vue 生态的未来方向。